home *** CD-ROM | disk | FTP | other *** search
/ Aminet 31 / Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso / Aminet / dev / c / vbccwossrc.lha / vbcc / pasm / directives.c next >
C/C++ Source or Header  |  1999-03-07  |  27KB  |  1,133 lines

  1. /* $VER: pasm directives.c V1.1d (27.09.98)
  2.  *
  3.  * This file is part of pasm, a portable PowerPC assembler.
  4.  * Copyright (c) 1997-98  Frank Wille
  5.  *
  6.  * pasm is freeware and part of the portable and retargetable ANSI C
  7.  * compiler vbcc, copyright (c) 1995-98 by Volker Barthelmann.
  8.  * pasm may be freely redistributed as long as no modifications are
  9.  * made and nothing is charged for it. Non-commercial usage is allowed
  10.  * without any restrictions.
  11.  * EVERY PRODUCT OR PROGRAM DERIVED DIRECTLY FROM MY SOURCE MAY NOT BE
  12.  * SOLD COMMERCIALLY WITHOUT PERMISSION FROM THE AUTHOR.
  13.  *
  14.  *
  15.  * v1.1d  (27.09.98) phx
  16.  *        Allow blanks after string constants.
  17.  * v1.1c  (22.09.98) phx
  18.  *        Include file name was trashed (allocstring() was missing).
  19.  * v1.1b  (05.07.98) phx
  20.  *        Introduced section flags SF_CHIP and SF_FAST for EHF/ADos. They
  21.  *        are set by the new section attributes "C" and "F".
  22.  * v1.1   (19.06.98) phx
  23.  *        New directive .sdreg which sets the small data base
  24.  *        register (default r2).
  25.  *        .SDREG replaces the obsolete .BASEREL directive!
  26.  * v1.0   (04.04.98) phx
  27.  *        Hack in _uahalf() to make ADDR16-relocation work for instructions.
  28.  * v0.8   (14.02.98) phx
  29.  *        Alignment list for each section. This fixes the problems
  30.  *        with optimizations.
  31.  * v0.6   (30.10.97) phx
  32.  *        The names of macros will be converted to lower case (otherwise,
  33.  *        they would remain inaccessible ;)
  34.  * v0.5   (12.10.97) phx
  35.  *        .set directive is allowed multiple times on the same symbol.
  36.  *        If a .set-assignment can't be resolved in pass 1, the symbol
  37.  *        is no longer undefined, but defined with an absolute default
  38.  *        value of '1'. So .ifdef will work correctly.
  39.  *        .globl directive declares unknown symbols in pass 1 as
  40.  *        externally defined. If the symbol is defined later in the
  41.  *        source, it will be made global by add_symbol()/tables.c.
  42.  * v0.4   (29.04.97) phx
  43.  *        .new_section sets type of section-symbol to SYMI_SECTION.
  44.  *        New directives: .baserel
  45.  * v0.3   (10.04.97) phx
  46.  *        Some vbcc-specific changes.
  47.  * v0.2   (25.03.97) phx
  48.  *        Writes ELF object for 32-bit PowerPC big-endian. Either absolute
  49.  *        or ELF output format may be selected. ELF is default for all
  50.  *        currently supported platforms. PPCasm supports nine different
  51.  *        relocation types (there are much more...).
  52.  *        Compiles and works also under NetBSD/amiga (68k).
  53.  *        Changed function declaration to 'new style' in all sources
  54.  *        (to avoid problems with '...' for example).
  55.  *        Floating pointer support. New directives: .fail, .ident, .file,
  56.  *        .float, .ufloat, .double, .udouble, .local.
  57.  * v0.1   (11.03.97) phx
  58.  *        First test version with all PowerPC instructions and most
  59.  *        important directives. Only raw, absolute output.
  60.  *        .ident and .file directives are supported, but have no effect.
  61.  *        Especially floating point directives are missing.
  62.  * v0.0   (21.02.97) phx
  63.  *        File created.
  64.  */
  65.  
  66.  
  67. #define DIRECTIVES_C
  68. #include "ppcasm.h"
  69.  
  70.  
  71. void activate_section(struct GlobalVars *,struct Section *);
  72. void alignment(struct GlobalVars *,unsigned long);
  73. char escchar(char);
  74.  
  75. static void start_section(struct GlobalVars *,struct ParsedLine *pl,bool);
  76. static char *section_attributes(struct GlobalVars *,char *,uint8 *,
  77.                                 uint8 *,uint8 *,uint8 *);
  78. static void _uahalf(struct GlobalVars *,struct ParsedLine *);
  79. static void _uaword(struct GlobalVars *,struct ParsedLine *);
  80. static void uafloat(struct GlobalVars *,struct ParsedLine *,bool);
  81. static void ifeqs(struct GlobalVars *,struct ParsedLine *,int);
  82. static void ifdef(struct GlobalVars *,struct ParsedLine *,bool);
  83.  
  84.  
  85.  
  86. static void _new_section(struct GlobalVars *gv,struct ParsedLine *pl)
  87. {
  88.   start_section(gv,pl,1);
  89. }
  90.  
  91.  
  92. static void _section(struct GlobalVars *gv,struct ParsedLine *pl)
  93. {
  94.   start_section(gv,pl,0);
  95. }
  96.  
  97.  
  98. static void start_section(struct GlobalVars *gv,struct ParsedLine *pl,
  99.                           bool force_new)
  100. /* define a new section with new attributes or reactivate a */
  101. /* previously defined one */
  102. {
  103.   struct Section *nexts,*sec = (struct Section *)gv->sectionlist.first;
  104.   struct Symbol *sym;
  105.   struct AlignPoint *ap;
  106.   char *s,*name;
  107.   uint8 type,flags,protection,alignment;
  108.  
  109.   s = getarg(gv,pl->operand);  /* section's name */
  110.   name = remquotes(gv->strbuf);
  111.  
  112.   while (nexts = (struct Section *)sec->n.next) {
  113.     if (!strcmp(name,sec->name)) {
  114.  
  115.       if (force_new) {  /* overwrite an old section with the same name? */
  116.         sprintf(gv->strbuf,"%s_%08lx",sec->name,(unsigned long)sec);
  117.         name = sec->name;
  118.         sec->name = allocstring(gv->strbuf);
  119.         break;
  120.       }
  121.  
  122.       else {  /* reactivate old section with the same name */
  123.         s = section_attributes(gv,s,&type,&flags,&protection,&alignment);
  124.         if (type != ST_UNDEFINED)  /* attributes specified? */
  125.           if (sec->type!=type || sec->flags!=flags ||
  126.               sec->protection!=protection || sec->alignment!=alignment)
  127.             error(16);  /* section attributes don't match */
  128.         pl->type = OT_SECTION;
  129.         pl->opcode = (void *)sec;
  130.         activate_section(gv,sec);
  131.         checkEOL(s);
  132.         return;
  133.       }
  134.  
  135.     }
  136.     sec = nexts;
  137.   }
  138.  
  139.   /* create a new section */
  140.   sec = alloczero(sizeof(struct Section));
  141.   sec->name = allocstring(name);
  142.   s = section_attributes(gv,s,&sec->type,&sec->flags,&sec->protection,
  143.                          &sec->alignment);
  144.   if (sec->type == ST_UNDEFINED) {  /* set default attributes */
  145.     sec->type = ST_DATA;
  146.     sec->protection = SP_READ|SP_WRITE;
  147.     sec->alignment = 2;
  148.   }
  149.   initlist(&sec->reloclist);
  150.   initlist(&sec->xreflist);
  151.   ap = alloc(sizeof(struct AlignPoint));
  152.   ap->next = NULL;
  153.   ap->offset = ap->gap = 0;
  154.   ap->val = 1 << sec->alignment;
  155.   sec->first_align = sec->current_align = ap;
  156.   addtail(&gv->sectionlist,&sec->n);
  157.   pl->type = OT_SECTION;
  158.   pl->opcode = (void *)sec;
  159.   activate_section(gv,sec);
  160.   sym = add_symbol(gv,sec->name,SYM_RELOC,0);
  161.   sym->info = SYMI_SECTION;
  162.   checkEOL(s);
  163. }
  164.  
  165.  
  166. void activate_section(struct GlobalVars *gv,struct Section *sec)
  167. {
  168.   gv->csect = sec;  /* set active section */
  169.   gv->lcsym->relsect = sec;
  170.   gv->lcsym->value = sec->pc;
  171. }
  172.  
  173.  
  174. static char *section_attributes(struct GlobalVars *gv,char *s,uint8 *t,
  175.                                 uint8 *f,uint8 *p,uint8 *a)
  176. /* fill in section attributes, if specified */
  177. {
  178.   char c,*attr;
  179.  
  180.   *t = ST_UNDEFINED;
  181.   *f = *p = *a = 0;
  182.   s = skipspaces(s);
  183.   if (*s) {
  184.     if (*s == ',') {
  185.       s = skipspaces(++s);
  186.       s = getarg(gv,s);
  187.       c = *gv->strbuf;
  188.       if (c=='\"' || c=='\'') {
  189.         attr = remquotes(gv->strbuf);
  190.         while (c = *attr++) {
  191.           switch (c) {
  192.             /* contents type */
  193.             case 'c':
  194.               *t = ST_CODE;
  195.               break;
  196.             case 'd':
  197.               *t = ST_DATA;
  198.               break;
  199.             case 'u':
  200.               *t = ST_UDATA;
  201.               *f |= SF_UNINITIALIZED;
  202.               break;
  203.             case 'i':
  204.               *t = ST_STRUCT;
  205.               *f |= SF_DISCARD|SF_UNINITIALIZED;
  206.               break;
  207.             /* protection */
  208.             case 'r':
  209.               *p |= SP_READ;
  210.               break;
  211.             case 'w':
  212.               *p |= SP_WRITE;
  213.               break;
  214.             case 'x':
  215.               *p |= SP_EXEC;
  216.               break;
  217.             case 's':
  218.               *p |= SP_SHARE;
  219.               break;
  220.             case 'n': /* remove and discard currently not supported */
  221.             case 'R':
  222.               break;
  223.             case 'C':
  224.               *f |= SF_CHIP;
  225.               break;
  226.             case 'F':
  227.               *f |= SF_FAST;
  228.               break;
  229.             default:
  230.               if (c>='0' && c <='6')
  231.                 *a = (uint8)(c-'0');  /* alignment */
  232.               else
  233.                 error(15,c);  /* illegal section attribute */
  234.               break;
  235.           }
  236.         }
  237.       }
  238.       else
  239.         error(14);  /* string constant expected */
  240.     }
  241.     else if (*s != '#')
  242.       error(12);  /* colon expected */
  243.   }
  244.   return (s);
  245. }